#include "mboard.h"
#include "mboard_private.h"
#include "exti_hw.h"
#include "gpio_hw.h"
#include "syscfg_hw.h"
#include "tim_base_hw.h"
#include "dma_hw.h"
#include "usart_hw.h"
#include "mgdb.h"

/* 滴答定时器在mboard.c中初始化 */
void SysTick_Handler(void)
{
	/* 不需要清中断，对ms进行累加 */
	mboardInfo.ms++;
}

void EXTI0_IRQHandler(void)
{
	/* 重置定时器，单脉冲模式下，UG会停止定时器 */
	SOC_TIM6.EGR = TIM_BASE_EGR_UG_EN;
	/* 启动定时器 */
	SOC_BITBAND_WRITE(SOC_BASE_TIM6, SOC_OFF_TIM_CR1, SOC_BIT_TIM_CR1_EN,
	                  SOC_VAL_TIM_CR1_RUN);
	/* 关闭中断 */
	SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
	                  SOC_BIT_EXTI_IMR_0_22D(0), SOC_VAL_EXTI_IMR_FORBID);
	/* 写1清除中断标志 */
	SOC_EXTI.PR = EXTI_PR_CLEAR_0_22D(0);
}

void EXTI2_IRQHandler(void)
{
	/* 重置定时器，单脉冲模式下，UG会停止定时器 */
	SOC_TIM6.EGR = TIM_BASE_EGR_UG_EN;
	/* 启动定时器 */
	SOC_BITBAND_WRITE(SOC_BASE_TIM6, SOC_OFF_TIM_CR1, SOC_BIT_TIM_CR1_EN,
	                  SOC_VAL_TIM_CR1_RUN);
	/* 关闭中断 */
	SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
	                  SOC_BIT_EXTI_IMR_0_22D(2), SOC_VAL_EXTI_IMR_FORBID);
	/* 写1清除中断标志 */
	SOC_EXTI.PR = EXTI_PR_CLEAR_0_22D(2);
}

void EXTI3_IRQHandler(void)
{
	/* 重置定时器，单脉冲模式下，UG会停止定时器 */
	SOC_TIM6.EGR = TIM_BASE_EGR_UG_EN;
	/* 启动定时器 */
	SOC_BITBAND_WRITE(SOC_BASE_TIM6, SOC_OFF_TIM_CR1, SOC_BIT_TIM_CR1_EN,
	                  SOC_VAL_TIM_CR1_RUN);
	/* 关闭中断 */
	SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
	                  SOC_BIT_EXTI_IMR_0_22D(3), SOC_VAL_EXTI_IMR_FORBID);
	/* 写1清除中断标志 */
	SOC_EXTI.PR = EXTI_PR_CLEAR_0_22D(3);
}

void EXTI4_IRQHandler(void)
{
	/* 重置定时器，单脉冲模式下，UG会停止定时器 */
	SOC_TIM6.EGR = TIM_BASE_EGR_UG_EN;
	/* 启动定时器 */
	SOC_BITBAND_WRITE(SOC_BASE_TIM6, SOC_OFF_TIM_CR1, SOC_BIT_TIM_CR1_EN,
	                  SOC_VAL_TIM_CR1_RUN);
	/* 关闭中断 */
	SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
	                  SOC_BIT_EXTI_IMR_0_22D(4), SOC_VAL_EXTI_IMR_FORBID);
	/* 写1清除中断标志 */
	SOC_EXTI.PR = EXTI_PR_CLEAR_0_22D(4);
}

void TIM6_DAC_IRQHandler(void)
{
	uint32_t val;

	/* TIM6和DAC公用一个中断号，此处需要判断一下 */
	if (_TIM_BASE_IsInterrupt(SOC_TIM6)) {
		/* 读取外部中断线状态，产生过中断的会关闭相应的中断 */
		val = SOC_EXTI.IMR;

		if ((val & EXTI_IMR_MASK_0_22D(0)) == EXTI_IMR_FORBID_0_22D(0)) {
			/* EXTI0: PA0有中断产生，使用位带方式读取PA0的值，
			   PA0默认下拉低电平 */
			if (SOC_BITBAND_READ(SOC_BASE_GPIOA, SOC_OFF_GPIO_IDR,
			                     SOC_BIT_GPIO_PIN_0_15D(0))
			     == SOC_VAL_GPIO_ODR_LOW) {
				mkeyInfo.state.up = MKEY_STATE_RELEASE;
			} else {
				mkeyInfo.state.up = MKEY_STATE_PRESS;
				mkeyInfo.count.up++;
			}

			/* 开启外部中断 */
			SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
			                  SOC_BIT_EXTI_IMR_0_22D(0),
			                  SOC_VAL_EXTI_IMR_PERMIT);
		}

		if ((val & EXTI_IMR_MASK_0_22D(2)) == EXTI_IMR_FORBID_0_22D(2)) {
			/* EXTI2: PE2有中断产生，使用位带方式读取PE2的值，
			   PE2默认上拉高电平 */
			if (SOC_BITBAND_READ(SOC_BASE_GPIOE, SOC_OFF_GPIO_IDR,
			                     SOC_BIT_GPIO_PIN_0_15D(2))
			     == SOC_VAL_GPIO_ODR_LOW) {
				mkeyInfo.state.left = MKEY_STATE_PRESS;
				mkeyInfo.count.left++;
			} else {
				mkeyInfo.state.left = MKEY_STATE_RELEASE;
			}

			/* 开启外部中断 */
			SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
			                  SOC_BIT_EXTI_IMR_0_22D(2),
			                  SOC_VAL_EXTI_IMR_PERMIT);
		}

		if ((val & EXTI_IMR_MASK_0_22D(3)) == EXTI_IMR_FORBID_0_22D(3)) {
			/* EXTI3: PE3有中断产生，使用位带方式读取PE3的值，
			   PE3默认上拉高电平 */
			if (SOC_BITBAND_READ(SOC_BASE_GPIOE, SOC_OFF_GPIO_IDR,
			                     SOC_BIT_GPIO_PIN_0_15D(3))
			     == SOC_VAL_GPIO_ODR_LOW) {
				mkeyInfo.state.down = MKEY_STATE_PRESS;
				mkeyInfo.count.down++;
			} else {
				mkeyInfo.state.down = MKEY_STATE_RELEASE;
			}

			/* 开启外部中断 */
			SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
			                  SOC_BIT_EXTI_IMR_0_22D(3),
			                  SOC_VAL_EXTI_IMR_PERMIT);
		}

		if ((val & EXTI_IMR_MASK_0_22D(4)) == EXTI_IMR_FORBID_0_22D(4)) {
			/* EXTI4: PE4有中断产生，使用位带方式读取PE4的值，
			   PE4默认上拉高电平 */
			if (SOC_BITBAND_READ(SOC_BASE_GPIOE, SOC_OFF_GPIO_IDR,
			                     SOC_BIT_GPIO_PIN_0_15D(4))
			     == SOC_VAL_GPIO_ODR_LOW) {
				mkeyInfo.state.right = MKEY_STATE_PRESS;
				mkeyInfo.count.right++;
			} else {
				mkeyInfo.state.right = MKEY_STATE_RELEASE;
			}

			/* 开启外部中断 */
			SOC_BITBAND_WRITE(SOC_BASE_EXTI, SOC_OFF_EXTI_IMR,
			                  SOC_BIT_EXTI_IMR_0_22D(4),
			                  SOC_VAL_EXTI_IMR_PERMIT);
		}

		/* SOC_TIM6.SR状态寄存器写0清中断 */
		_TIM_BASE_ClearInterrupt(SOC_TIM6);
	}
}

void USART1_IRQHandler(void)
{
	uint32_t sr = SOC_USART1.SR;

	/* 检测错误标志 */
	if (sr & (USART_SR_PE | USART_SR_FE | USART_SR_NF | USART_SR_ORE)) {
		/* 奇偶校验错误 */
		if (sr & USART_SR_PE) {
		}

		/* 帧错误 */
		if (sr & USART_SR_FE) {
		}

		/* 检测到噪声 */
		if (sr & USART_SR_NF) {
		}

		/* 接收上溢错误 */
		if (sr & USART_SR_ORE) {
		}
		while (1);
	}

	/* 中断标志在回调函数中清除 */
	/* 接收中断 */
	if (sr & USART_SR_RXNE) {
		/* 关闭RX中断，使用DMA接收数据 */
		SOC_BITBAND_WRITE(SOC_BASE_USART1, SOC_OFF_USART_CR1,
		          SOC_BIT_USART_CR1_RXNEIE, SOC_VAL_USART_CR1_RXNEIE_DIS);
		mUsartRxDmaStart();
	}

	if (sr & USART_SR_IDLE) {
		mUsartRxIdle();
	}
}

void DMA2_Stream5_IRQHandler(void)
{
	uint32_t sr = SOC_DMA2.ISR[DMA_IDX_4_7D(5)];
	uint32_t ch = _DMA_GetChannel(SOC_DMA2_S5);
	
	/* 检测错误标志 */
	if (sr & (DMA_S5_FLAG(DMA_FLAG_FEIF) | DMA_S5_FLAG(DMA_FLAG_DMEIF) | 
			  DMA_S5_FLAG(DMA_FLAG_TEIF))) {
		/* FIFO错误 */
		if (sr & DMA_S5_FLAG(DMA_FLAG_FEIF)) {
		}
		/* 直接模式错误 */
		if (sr & DMA_S5_FLAG(DMA_FLAG_DMEIF)) {
		}
		/* 传输错误 */
		if (sr & DMA_S5_FLAG(DMA_FLAG_TEIF)) {
		}
		while (1);
	}

	/* 中断标志在回调函数中清除了 */
	/* 半传输中断 */
	if (sr & DMA_S5_FLAG(DMA_FLAG_HTIF)) {
	}

	/* 传输完成中断 */
	if (sr & DMA_S5_FLAG(DMA_FLAG_TCIF)) {
		switch (ch) {
			case 0:  // NONE
				break;
			case 1:  // NONE
				break;
			case 2:  // CRYP_OUT
				break;
			case 3:  // SPI1_TX
				break;
			case 4:  // USART1_RX
				mUsartRxDmaTCI();
				break;
			case 5:  // NONE
				break;
			case 6:  // TIM1_UP
				break;
			case 7:  // NONE
				break;
		}
	}
}

void DMA2_Stream7_IRQHandler(void)
{
	uint32_t sr = SOC_DMA2.ISR[DMA_IDX_4_7D(7)];
	uint32_t ch = _DMA_GetChannel(SOC_DMA2_S7);
	
	/* 检测错误标志 */
	if (sr & (DMA_S7_FLAG(DMA_FLAG_FEIF) | DMA_S7_FLAG(DMA_FLAG_DMEIF) | 
			  DMA_S7_FLAG(DMA_FLAG_TEIF))) {
		/* FIFO错误 */
		if (sr & DMA_S7_FLAG(DMA_FLAG_FEIF)) {
		}
		/* 直接模式错误 */
		if (sr & DMA_S7_FLAG(DMA_FLAG_DMEIF)) {
		}
		/* 传输错误 */
		if (sr & DMA_S7_FLAG(DMA_FLAG_TEIF)) {
		}
		while (1);
	}

	/* 中断标志在回调函数中清除了 */
	/* 半传输中断 */
	if (sr & DMA_S7_FLAG(DMA_FLAG_HTIF)) {
	}

	/* 传输完成中断 */
	if (sr & DMA_S7_FLAG(DMA_FLAG_TCIF)) {
		switch (ch) {
			case 0:  // NONE
				break;
			case 1:  // DCMI
				break;
			case 2:  // HASH_IN
				break;
			case 3:  // NONE
				break;
			case 4:  // USART1_TX
				mUsartTxDmaTCI();
				break;
			case 5:  // USART6_TX
				break;
			case 6:  // 
				break;
			case 7:  // TIM8_CH4/TIM8_TRIG/TIM8_COM
				break;
		}
	}
}

void SDIO_IRQHandler(void)
{
	while (1);
}
